﻿using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;
using OpenLS.Spreadsheet.Drawing;
using OpenLS.Spreadsheet.Formats.Biff.OfficeArt;

namespace OpenLS.Spreadsheet.Formats.Biff.Records
{
    internal class NoteRecord : WorksheetLevelRecord
    {
        private NoteContent _body;

        public NoteRecord(Cell cell, BiffWriterWorkbookContext context)
        {
            Contract.Requires(cell != null);
            Contract.Requires(cell.Comment != null);
            Contract.Requires(context != null);
            _body = new NoteSh(cell, context);
        }

        public NoteRecord()
        {
        }

        internal override BiffRecordType RecordType
        {
            get { return BiffRecordType.Note; }
        }

        internal override void Apply(BiffReaderWorksheetContext context)
        {
//#if COMMENTS
            if (_body is NoteSh)
            {
                var noteSh = (NoteSh) _body;
                var comment = new Comment();
                string author = noteSh.Author;
                ObjRecord objRecord = context.ObjRecords[noteSh.IdObj];
                OfficeArtRecord record = objRecord.OfficeArtClientData;
                Cell targetCell = context.Worksheet[noteSh.Row, noteSh.Column];
                targetCell.Comment = comment;
                comment.IsVisible = noteSh.IsVisible;
                if (record != null)
                {
                    var container = (OfficeArtSpContainer) record.Parent;
                    if (container != null)
                    {
                        OfficeArtClientTextbox textbox = container.ClientTextbox;
                        if (textbox != null)
                        {
                            RichTextParagraph text = textbox.TxoRecord.GetRichTextParagraph(context);
                            if (text != null)
                                comment.Text = text;
                        }
                        OfficeArtClientAnchorSheet client = container.ClientAnchor;
                        if (client != null)
                        {
                            var anchor = client.ToAnchor(context.Worksheet);
                            if (anchor is AbsoluteAnchor)
                            {
                                comment.TopMargin = anchor.RowOffset;
                                comment.LeftMargin = anchor.ColumnOffset;
                                comment.Width = anchor.ActualWidth;
                                comment.Height = anchor.ActualHeight;
                            }
                            else if (anchor is TwoCellAnchor)
                            {
                                TwoCellAnchor twoCellAnchor = (TwoCellAnchor) anchor;
                                comment.TopMargin = twoCellAnchor.RowOffset;
                                comment.LeftMargin = twoCellAnchor.ColumnOffset;
                                comment.Width = anchor.ActualWidth;
                                comment.Height = anchor.ActualHeight;
                            }
                            else
                            {
                                // Contract.Assert(false);
                            }
                        }
                    }
                }
                if (author != null)
                    comment.Author = author;
            }
        }

        internal override void WriteContent(BiffWriterWorkbookContext context)
        {
            WriteWriter(context.Writer);
        }

        private void WriteWriter(BinaryWriter writer)
        {
            _body.Write(writer);
        }


        protected override void ReadContent(BiffReaderContext context, int length)
        {
            ReadReader(context.Reader);
            //\\ different in revision...
        }

        private void ReadReader(BinaryReader reader)
        {
#if DEBUG
            long position = reader.BaseStream.Position;
            ReadWriteChecker.CheckClass((t, r) => t.ReadReader(r),
                                        (t, w) => t.WriteWriter(w), reader, this);
#endif
            var body = new NoteSh();
            _body = body;
            _body.Read(reader);
        }
    }
}